﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using CppIDE.Core;
using Application = CppIDE.Core.Application;

namespace CppIDE.UI
{

    /// <summary>
    /// Egy megnyitott fájl fülét és a fülhez tartozó tartalmat kezelő megjelenítő osztály.
    /// </summary>
    public class FileTabPage : TabPage
    {

        /// <summary>
        /// A fülön szereplő szerkesztőmező
        /// </summary>
        private SyntaxEdit editor = new SyntaxEdit();

        /// <summary>
        /// Konstruktor, létrehoz egy új példányt
        /// </summary>
        public FileTabPage()
        {
            File = null;
            Saved = false;
            initialize();
            editor.Text = null;
        }

        /// <summary>
        /// Konstruktor, létrehoz egy új példányt az adott fájlhoz
        /// </summary>
        /// <param name="file">a megnyitandó fájl</param>
        public FileTabPage(SourceFile file)
        {
            File = file;
            Saved = true;
            editor.Text = file.Content;
            editor.colorizeFull();
            initialize();
        }

        /// <summary>
        /// Inicializáció: a két konstruktor közös része van itt.
        /// </summary>
        private void initialize()
        {
            Padding = new Padding(0, 2, 0, 0);
            editor.Dock = DockStyle.Fill;
            Controls.Add(editor);
            editor.TextChanged += delegate(object s, EventArgs a)
            {
                Saved = false;
            };
        }

        /// <summary>
        /// Ha megváltozik a mentettség állapota, akkor ez az esemény megtörténik.
        /// </summary>
        public event EventHandler SavedChange;

        /// <summary>
        /// Ha igaz, akkor a fájl nem tartalmaz mentetlen módosítást.
        /// </summary>
        private bool saved;

        /// <summary>
        /// Ha igaz, akkor a fájl nem tartalmaz mentetlen módosítást.
        /// Kívülről nem változtatható.
        /// </summary>
        /// <value>Ha igaz, akkor a fájl nem tartalmaz mentetlen módosítást.</value>
        public bool Saved
        {
            get
            {
                return saved;
            }
            private set
            {
                if (value != saved)
                {
                    saved = value;
                    try
                    {
                        SavedChange(this, null);
                    }
                    catch (NullReferenceException)
                    {
                    }
                    updateText();
                }
            }
        }

        /// <summary>
        /// Menti a fájlt, ha szükséges.
        /// </summary>
        /// <returns>a fájl mentett-e?</returns>
        public bool save()
        {
            if (file == null)
            {
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Filter =
                    "C++ forrásfájl (*.cpp;*.cxx;*.cc)|*.cpp;*.cxx;*.cc|" +
                    "Header fájl (*.h;*.hpp;*.hxx)|*.h;*.hpp;*.hxx|" +
                    "C forrásfájl (*.c)|*.c";
                Application application = Application.getInstance();
                if (application.isProjectLoaded())
                {
                    Project project = application.ActiveProject;
                    dialog.InitialDirectory = project.DirPath;
                }
                if (dialog.ShowDialog() != DialogResult.OK)
                {
                    return Saved;
                }
                file = SourceFile.factory(dialog.FileName);
            }
            if (!Saved)
            {
                file.Content = editor.Text;
                Saved = true;
            }
            return Saved;
        }

        /// <summary>
        /// A fülhöz társított fájl
        /// </summary>
        private SourceFile file = null;

        /// <summary>
        /// A fülhöz társított fájl tulajdonság. Legfeljebb egyszer állítható be.
        /// </summary>
        /// <value>A fülhöz társított fájl.</value>
        public SourceFile File
        {
            get
            {
                return file;
            }
            set
            {
                if (file != null)
                {
                    throw new Exception("File is already set!");
                }
                file = value;
                updateText();
            }
        }

        /// <summary>
        /// Frissíti a fülön szereplő szöveget: a végére kerül egy *, ha mentetlen.
        /// Ha pedig még nincs hozzá társított fájl, akkor a név "Névtelen".
        /// </summary>
        private void updateText()
        {
            if (file != null)
            {
                Text = file.Name;
            }
            else
            {
                Text = "Névtelen";
            }
            if (!Saved)
            {
                Text += "*";
            }
        }

        /// <summary>
        /// Odaugrik a fájlban a megadott sorhoz.
        /// </summary>
        /// <param name="lineNumber">a keresett sor száma</param>
        public void gotoLine(int lineNumber)
        {
            editor.gotoLine(lineNumber);
        }

        /// <summary>
        /// Aktiválja a fület és a kurzor bekerül a szerkesztőmezőbe.
        /// </summary>
        /// <returns></returns>
        public new bool Focus()
        {
            return base.Focus() && editor.Focus();
        }

    }

}
